#include "ds1302.h"
#include "intrins.h"
void write_data(unsigned char command, unsigned char datetime)
{
    DSCLK = 0;
    // 使能
    DS1302CE = 1;
    _nop_();
    // 开始写命令，从低位开始写
    for (i = 0; i < 8; i++)
    {
        DS1302IO = command & (0x01 << i);
        // 上升沿写数据
        _nop_();
        DSCLK = 1;
        _nop_();
        DSCLK = 0;
    }

    // 开始写数据
    for (i = 0; i < 8; i++)
    {
        DS1302IO = datetime & (0x01 << i);
        // 上升沿写数据
        _nop_();
        DSCLK = 1;
        _nop_();
        DSCLK = 0;
    }

    // 使不能
    _nop_();
    DS1302CE = 0;
    _nop_();
}

unsigned char read_data(unsigned char command)
{
    // 使能
    DS1302CE = 1;
    _nop_();
    // 开始写命令
    for (i = 0; i < 8; i++)
    {
        DSCLK = 0;
        DS1302IO = command & (0x01 << i);
        // 上升沿写命令
        _nop_();
        DSCLK = 1;
        _nop_();
    }

    // 开始读数据
    unsigned char temp = 0x00;
    for (i = 0; i < 8; i++)
    {
        // 下降沿读数据
        DSCLK = 0;
        _nop_();
        if (DS1302IO)
        {
            // 如果数据为1，则将tempde第i位置1
            temp |= (0x01 << i);
        }
        DSCLK = 1;
        _nop_();
    }
    DS1302CE = 0;
    _nop_();
    DS1302IO = 0;
    _nop_();
    DS1302IO = 1;
    _nop_();
    return temp;
}

int decimal_bcd_code(int decimal)
{
    // sum返回的BCD码
    int sum = 0;

    for (int i = 0; decimal > 0; i++)
    {
        sum |= ((decimal % 10) << (4 * i));

        decimal /= 10;
    }

    return sum;
}

int bcd_decimal_code(int bcd)
{
    // sum返回十进制，c每次翻10倍
    int sum = 0, c = 1;

    for (int i = 1; bcd > 0; i++)
    {
        if (i >= 2)
        {
            c *= 10;
        }

        sum += (bcd % 16) * c;
        // 除以16同理与十进制除10将小数点左移一次，取余16也同理
        bcd /= 16;
    }

    return sum;
}

void init_ds1302(unsigned int year, unsigned int month, unsigned int day, unsigned int hour, unsigned int min, unsigned int sec, unsigned int wek)
{
    // 关闭写保护
    write_data(WRITE_PRO, 0x00);

    // 写数据
    int bcd_year = decimal_bcd_code(year);
    write_data(WRITE_COMMAND[6], bcd_year);

    int bcd_wek = decimal_bcd_code(wek);
    write_data(WRITE_COMMAND[5], bcd_wek);

    int bcd_month = decimal_bcd_code(month);
    write_data(WRITE_COMMAND[4], bcd_month);

    int bcd_day = decimal_bcd_code(day);
    write_data(WRITE_COMMAND[3], bcd_day);

    int bcd_hour = decimal_bcd_code(hour);
    write_data(WRITE_COMMAND[2], bcd_hour);

    int bcd_min = decimal_bcd_code(min);
    write_data(WRITE_COMMAND[1], bcd_min);

    int bcd_sec = decimal_bcd_code(sec);
    write_data(WRITE_COMMAND[0], bcd_sec);

    // 打开写保护
    write_data(WRITE_PRO, 0x80);
}

unsigned int read_ds1302()
{
    int date_array[7]={0};
    for (i = 0; i < 7; i++)
    {
        //读取时间
        unsigned char readcommand = READ_COMMAND[i];
        unsigned char datetime = read_data(readcommand);
        //bcd时间转十进制
        int bcddate=bcd_decimal_code(datetime);
        date_array[i]=bcddate;
    }
    return date_array;
}